using System;
using System.IO;
using System.Web;
using System.Text;
using System.Reflection;
using System.Globalization;
using System.Collections.Generic;

namespace RealDolmen.Helpers
{
    public class Helper
    {
        #region Combine Strings
        public static string CombineStrings(string separator, params string[] strings)
        {
            List<string> result = new List<string>();

            for (int i = 0; i + 1 < strings.Length; i += 2)
            {
                string substring = strings[i];
                string subseparator = strings[i + 1];

                if (!string.IsNullOrEmpty(substring))
                {
                    string[] subarray = substring.Split(new string[] { subseparator }, StringSplitOptions.RemoveEmptyEntries);

                    foreach (string element in subarray)
                    {
                        string trimmedElement = element.Trim();

                        if (!string.IsNullOrEmpty(trimmedElement) && !result.Contains(trimmedElement))
                            result.Add(trimmedElement);
                    }
                }
            }

            return string.Join(separator, result.ToArray());
        }
        #endregion // Combine Strings

        #region GetAssemblyResource
        public static string GetAssemblyResource(string fullId)
        {
            return GetAssemblyResource(fullId, Assembly.GetExecutingAssembly());
        }

        public static string GetAssemblyResource(string fullId, Assembly assembly)
        {
            Stream s = assembly.GetManifestResourceStream(fullId);
            StreamReader sr = new StreamReader(s);
            return sr.ReadToEnd();
        }
        #endregion // GetAssemblyResource

        #region GetHttpResource
        public static string GetHttpResource(string content)
        {
            return GetHttpResource(content, string.Empty);
        }

        public static string GetHttpResource(string content, string defaultClassKey)
        {
            string keyword = "$resources:";

            int idx = content.ToLower().IndexOf(keyword);

            if (idx > -1)
            {
                string resourceString = content.Substring(idx + keyword.Length);

                string[] parts = resourceString.Split(',');
                if (parts.Length > 1)
                {
                    string classKey = parts[0].Trim();
                    if (string.IsNullOrEmpty(classKey))
                        classKey = defaultClassKey;

                    string resourceKey = parts[1].Trim();

                    if (!string.IsNullOrEmpty(classKey) && !string.IsNullOrEmpty(resourceKey))
                    {
                        object result = HttpContext.GetGlobalResourceObject(classKey, resourceKey);
                        if (result != null)
                            content = result.ToString();
                    }
                }

            }
            return content;
        }
        
        #endregion // ParseResources

        #region ConvertToHexPair
        public static void ConvertULongToInt32HexPair(ulong value, out string high, out string low)
        {
            high = "0x" + ((value >> 0x20)).ToString("X", CultureInfo.InvariantCulture);
            low = "0x" + ((value & 0xffffffffL)).ToString("X", CultureInfo.InvariantCulture);
        }
        
        #endregion // ConvertToHexPair

        #region GetOrDefault
        public static string GetStringOrDefault(string value, string defaultValue)
        {
            if (string.IsNullOrEmpty(value))
                return defaultValue;
            else
                return value;
        }

        public static int GetIntegerOrDefault(string value, int defaultValue)
        {
            int temp;

            if (string.IsNullOrEmpty(value))
                return defaultValue;
            else if (int.TryParse(value.ToString(), out temp))
                return temp;
            else
                return defaultValue;
        }

        public static bool GetBooleanOrDefault(string value, bool defaultValue)
        {
            bool temp;

            if (string.IsNullOrEmpty(value))
                return defaultValue;
            else if (bool.TryParse(value.ToString(), out temp))
                return temp;
            else if (value.ToString().Equals("on", StringComparison.InvariantCultureIgnoreCase))
                return true;
            else if (value.ToString().Equals("off", StringComparison.InvariantCultureIgnoreCase))
                return false;
            else
                return defaultValue;
        }

        public static DateTime GetDateTimeOrDefault(string value, DateTime defaultValue)
        {
            DateTime temp;

            if (string.IsNullOrEmpty(value))
                return defaultValue;
            else if (DateTime.TryParse(value.ToString(), out temp))
                return temp;
            else
                return defaultValue;
        }
        #endregion // GetOrDefault

        #region ConvertToType
        public static object ConvertToType(object value, Type type)
        {
            if (value != null && value.GetType() == typeof(string))
            {
                if (type == typeof(bool))
                {
                    return GetBooleanOrDefault(value.ToString(), false);
                }
                else if (type == typeof(int))
                {
                    return GetIntegerOrDefault(value.ToString(), -1);
                }
                else if (type.IsEnum)
                {
                    return Enum.Parse(type, value.ToString());
                }
                return value.ToString();
            }
            return value;
        } 
        #endregion // ConvertToType

        #region GetEnumValue
        public static T GetEnumValue<T>(string strValue, T defaultValue)
        {
            object value = Enum.Parse(typeof(T), strValue);

            if (value == null)
                return defaultValue;
            else
                return (T)value;
        }
        #endregion // GetEnumValue

        #region ConvertToAlphaNumericalAsciiString
        public static string ConvertToAlphaNumericalAsciiString(string inputString)
        {
            string newString = string.Empty, charString;
            char ch;
            int charsCopied;

            for (int i = 0; i < inputString.Length; i++)
            {
                charString = inputString.Substring(i, 1);
                charString = charString.Normalize(NormalizationForm.FormKD);
                if (charString.Length == 1)
                {
                    ch = ConvertToAlphaNumericalChar(charString[0]);
                    if (ch > char.MinValue)
                        newString += ch;
                }
                else
                {
                    charsCopied = 0;
                    for (int j = 0; j < charString.Length; j++)
                    {
                        ch = charString[j];
                        // If the char is 7-bit ASCII, add
                        if (ch < 128)
                        {
                            ch = ConvertToAlphaNumericalChar(charString[0]);
                            if (ch > char.MinValue)
                                newString += ch;
                            charsCopied++;
                        }
                    }
                    /* If we've decomposed non-ASCII, give it back
                     * in its entirety, since we only mean to decompose
                     * Latin chars.
                    */
                    if (charsCopied == 0)
                        newString += inputString.Substring(i, 1);
                }
            }
            return newString;
        }


        public static string ConvertToLowerAlphaNumericalDashedAsciiString(string inputString)
        {
            string newString = string.Empty, charString;
            char ch;
            int charsCopied;

            for (int i = 0; i < inputString.Length; i++)
            {
                charString = inputString.Substring(i, 1);
                charString = charString.Normalize(NormalizationForm.FormKD);
                if (charString.Length == 1)
                {
                    ch = ConvertToLowerAlphaNumericalChar(charString[0]);
                    ch = ConvertToDashIfNecessary(newString, ch);
                    if (ch > char.MinValue)
                        newString += ch;
                }
                else
                {
                    charsCopied = 0;
                    for (int j = 0; j < charString.Length; j++)
                    {
                        ch = charString[j];
                        // If the char is 7-bit ASCII, add
                        if (ch < 128)
                        {
                            ch = ConvertToLowerAlphaNumericalChar(charString[0]);
                            ch = ConvertToDashIfNecessary(newString, ch);
                            if (ch > char.MinValue)
                                newString += ch;
                            charsCopied++;
                        }
                    }
                    /* If we've decomposed non-ASCII, give it back
                     * in its entirety, since we only mean to decompose
                     * Latin chars.
                    */
                    if (charsCopied == 0)
                        newString += inputString.Substring(i, 1);
                }
            }
            return newString;
        }

        private static char ConvertToDashIfNecessary(string current, char nextChar)
        {
            if (nextChar == '-' || nextChar == ' ')
            {
                if (current.Length == 0 || current[current.Length - 1] != '-')
                    return '-';
                else
                    return char.MinValue;
            }
            return nextChar;
        }

        public static char ConvertToLowerAlphaNumericalChar(char c)
        {
            if ('a' <= c && c <= 'z')
                return c;
            else if ('0' <= c && c <= '9')
                return c;
            else if ('A' <= c && c <= 'Z')
                return (char)((int)c + ((int)'a' - (int)'A'));
            else if (c == '-' || c == ' ')
                return c;
            else
                return char.MinValue;
        }

        public static char ConvertToAlphaNumericalChar(char c)
        {
            if ('a' <= c && c <= 'z')
                return c;
            else if ('0' <= c && c <= '9')
                return c;
            else if ('A' <= c && c <= 'Z')
                return c;
            else if (c == '-' || c == ' ')
                return c;
            else
                return char.MinValue;
        } 
        #endregion // ConvertToAlphaNumericalAsciiString

        #region GetAssemblyFileVersion
        public static string GetAssemblyFileVersion(Assembly assembly)
        {
            string fileVer = string.Empty;
            if (assembly != null)
            {
                Attribute[] attributes = Attribute.GetCustomAttributes(assembly, typeof(AssemblyFileVersionAttribute));
                if (attributes.Length > 0)
                {
                    AssemblyFileVersionAttribute va = (AssemblyFileVersionAttribute)attributes[0];
                    fileVer = va.Version;
                }
                else
                {
                    fileVer = string.Empty;
                }
            }
            return fileVer;
        } 
        #endregion // GetAssemblyFileVersion

        #region CreateRandomString
        public static string CreateRandomString(int length)
        {
            string _allowedChars = "abcdefghijkmnopqrstuvwxyz0123456789";

            char[] chars = new char[length];
            Random r = new Random();

            for (int i = 0; i < length; i++)
            {
                chars[i] = _allowedChars[r.Next(_allowedChars.Length)];
            }

            return new string(chars);
        } 
        #endregion // CreateRandomString
    }
}
